﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;


namespace GameSchool.Models
{
    public class GameSchoolContext : DbContext
    {
        public DbSet<Achievement> achievements {get; set; }
        public DbSet<Student> students { get; set; }
        public DbSet<Course> courses { get; set; }
        public DbSet<Teacher> teachers { get; set; }
        public DbSet<Level> levels { get; set; }
        public DbSet<Exam> exams { get; set; }
        public DbSet<Assignment> assignments { get; set; }
        public DbSet<Lecture> lectures { get; set; }
        public DbSet<Question> questions { get; set; }
        public DbSet<Answer> answers { get; set; }
        public DbSet<Comment> comments { get; set; }
        public DbSet<Like> likes { get; set; }

        //Combined tables
        public DbSet<TeacherCourse> teacherCourses { get; set; }
        public DbSet<StudentCourse> studentCourses { get; set; }
        public DbSet<StudentAssignment> studentAssignments { get; set; }
        public DbSet<StudentExam> studentExams { get; set; }
        public DbSet<StudentLecture> studentLectures { get; set; }
        public DbSet<StudentLevel> studentLevels { get; set; }
        public DbSet<CourseAchievement> courseAchievements { get; set; }
        public DbSet<AchievementCourseStudent> achievementCourseStudents { get; set; }
    
        static GameSchoolContext()
        {
            // this line below needs to be uncommented if we're going to make changes to the database. Daniel advised that we should
            // be very careful when we do that. That is to say, let's try to keep the database as it is for a while and focus on writing unit
            // test, classes, etc. before we open up this can of worms again. -eiki, on friday afternoon
           // Database.SetInitializer(new MyDbContextInitializer()); 
        } 

        // this function was required to prevent infinite loop problems with the database - eiki
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Like>()
                        .HasRequired(e => e.student)
                        .WithMany(s => s.likes ) 
                        .HasForeignKey(e => e.studentID)
                        .WillCascadeOnDelete(false);

            #region TeacherCourse
            modelBuilder.Entity<TeacherCourse>()
                .HasKey(tc => new { tc.teacherID, tc.courseID });

            modelBuilder.Entity<Teacher>()
                .HasMany(t => t.teacherCourses)
                .WithRequired()
                .HasForeignKey(tc => tc.teacherID);

            modelBuilder.Entity<Course>()
                .HasMany(c => c.teacherCourses)
                .WithRequired()
                .HasForeignKey(tc => tc.courseID);
            #endregion

            #region StudentCourse
            modelBuilder.Entity<StudentCourse>()
                .HasKey(sc => new { sc.studentID, sc.courseID });

            modelBuilder.Entity<Student>()
                .HasMany(s => s.studentCourses)
                .WithRequired()
                .HasForeignKey(sc => sc.studentID);

            modelBuilder.Entity<Course>()
                .HasMany(c => c.studentCourses)
                .WithRequired()
                .HasForeignKey(sc => sc.courseID);
            #endregion

            #region StudentAssignment
            modelBuilder.Entity<StudentAssignment>()
                .HasKey(sa => new { sa.studentID, sa.assignmentID });

            modelBuilder.Entity<Student>()
                .HasMany(s => s.studentAssignments)
                .WithRequired()
                .HasForeignKey(sa => sa.studentID);

            modelBuilder.Entity<Assignment>()
                .HasMany(a => a.studentAssignments)
                .WithRequired()
                .HasForeignKey(sa => sa.assignmentID);
            #endregion

            #region StudentExam
            modelBuilder.Entity<StudentExam>()
                .HasKey(se => new { se.studentID, se.examID });

            modelBuilder.Entity<Student>()
                .HasMany(s => s.studentExams)
                .WithRequired()
                .HasForeignKey(se => se.studentID);

            modelBuilder.Entity<Exam>()
                .HasMany(e => e.studentExams)
                .WithRequired()
                .HasForeignKey(se => se.examID);
            #endregion

            #region StudentLecture
            modelBuilder.Entity<StudentLecture>()
                .HasKey(sl => new { sl.studentID, sl.lectureID });

            modelBuilder.Entity<Student>()
                .HasMany(s => s.studentLectures)
                .WithRequired()
                .HasForeignKey(sl => sl.studentID);

            modelBuilder.Entity<Lecture>()
                .HasMany(l => l.studentLectures)
                .WithRequired()
                .HasForeignKey(sl => sl.lectureID);
            #endregion

            #region StudentLevel
            modelBuilder.Entity<StudentLevel>()
                .HasKey(sl => new { sl.studentID, sl.levelID });

            modelBuilder.Entity<Student>()
                .HasMany(s => s.studentLevels)
                .WithRequired()
                .HasForeignKey(sl => sl.studentID);

            modelBuilder.Entity<Level>()
                .HasMany(l => l.studentLevels)
                .WithRequired()
                .HasForeignKey(sl => sl.levelID);
            #endregion

            #region CourseAchievement
            modelBuilder.Entity<CourseAchievement>()
                .HasKey(ca => new { ca.courseID, ca.achievementID });

            modelBuilder.Entity<Course>()
                .HasMany(c => c.courseAchievements)
                .WithRequired()
                .HasForeignKey(ca => ca.courseID);

            modelBuilder.Entity<Achievement>()
                .HasMany(a => a.courseAchievements)
                .WithRequired()
                .HasForeignKey(ca => ca.achievementID);
            #endregion

            #region AchievementCourseStudent
            modelBuilder.Entity<AchievementCourseStudent>()
                .HasKey(acs => new { acs.achievementID, acs.courseID, acs.studentID });

            modelBuilder.Entity<Achievement>()
                .HasMany(a => a.achievementCourseStudents)
                .WithRequired()
                .HasForeignKey(acs => acs.achievementID);

            modelBuilder.Entity<Course>()
                .HasMany(c => c.achievementCourseStudents)
                .WithRequired()
                .HasForeignKey(acs => acs.courseID);

            modelBuilder.Entity<Student>()
                .HasMany(s => s.achievementCourseStudents)
                .WithRequired()
                .HasForeignKey(acs => acs.studentID);
            #endregion
        }
    }
    
    public class MyDbContextInitializer : DropCreateDatabaseIfModelChanges<GameSchoolContext>
    {

        protected override void Seed(GameSchoolContext dbContext)
        {
            //seed data
            // this is where we define what data should be in the database when it gets initialized - eiki
            Course c = new Course();
            c.courseID = 3;

            
          //  dbContext.Database.ExecuteSqlCommand("ALTER DATABASE GameSchool SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
            base.Seed(dbContext);
        }
    }



    /*
    public class ForceDeleteInitializer : IDatabaseInitializer<GameSchoolContext>
    {
        private readonly IDatabaseInitializer<GameSchoolContext> _initializer;

        public ForceDeleteInitializer(IDatabaseInitializer<GameSchoolContext> innerInitializer)
        {
            _initializer = innerInitializer;
        }

        public void InitializeDatabase(GameSchoolContext context)
        {
            context.Database.ExecuteSqlCommand("ALTER DATABASE GameSchool SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
            _initializer.InitializeDatabase(context);
        }
    }*/
}